package cn.com.bluemoon.daps.model.utils.contrast;

import cn.com.bluemoon.daps.common.domain.ResultBean;
import cn.com.bluemoon.daps.common.domain.UserInfoHolder;
import cn.com.bluemoon.daps.common.enums.DatabaseType;
import cn.com.bluemoon.daps.common.sql.SqlScriptUtils;
import cn.com.bluemoon.daps.domp.api.IDompService;
import cn.com.bluemoon.daps.model.dto.*;
import cn.com.bluemoon.daps.model.entity.*;
import cn.com.bluemoon.daps.model.utils.SqlUtils;
import cn.com.bluemoon.daps.model.utils.factory.impl.field.AbsFieldScript;
import cn.com.bluemoon.daps.model.utils.factory.impl.field.HiveFieldScript;
import cn.com.bluemoon.daps.model.utils.factory.impl.key.AbsKeyScript;
import cn.com.bluemoon.daps.model.utils.factory.impl.table.AbsTableScript;
import cn.com.bluemoon.daps.model.utils.factory.impl.table.HiveTableScript;
import cn.com.bluemoon.daps.model.utils.factory.impl.table.MysqlTableScript;
import cn.com.bluemoon.daps.model.utils.factory.impl.table.PostgreTableScript;
import cn.com.bluemoon.daps.sync.base.BmScript;
import cn.com.bluemoon.daps.sync.base.CompareResult;
import cn.com.bluemoon.daps.sync.base.ModifyType;
import cn.com.bluemoon.daps.sync.base.SqlCompareResult;
import cn.com.bluemoon.daps.sync.vo.applypublish.ModelCompareVo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.sun.org.apache.xpath.internal.operations.Bool;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

public class VersionContrast {

    private static final Integer CREATE_TABLE = 1;
    private static final Integer DELETE_TABLE = 2;
    private static final Integer MODIFY_TABLE = 3;
    public static AbsTableScript script = null;

    /**
     * 模型表对比
     *
     * @param newModel
     * @param oldModel
     * @param databaseType
     */
    public static ResultBean<List<DapDataModelOperateHistory>> modelContrast(List<DapDataModelTableDto> newModel, DatabaseType databaseType,
                                                                             List<DapDataModelTableDto> oldModel, LocalDateTime max, boolean flag) {

        List<String> newIds = newModel.stream().map(DapDataModelTableDto::getTableId).collect(Collectors.toList());
        List<String> sameIds = oldModel.stream().filter(f -> newIds.contains(f.getPId()))
                .map(DapDataModelTableDto::getPId)
                .collect(Collectors.toList()); // 新旧数据交集id
        List<DapDataModelTableDto> addTable = newModel.stream().filter(n -> !sameIds.contains(n.getTableId()))
                .collect(Collectors.toList()); // 新建表
        List<DapDataModelTableDto> deleteTable = oldModel.stream().filter(o -> !sameIds.contains(o.getPId()))
                .collect(Collectors.toList()); // 删除表
        List<String> modifyIds = newModel.stream().filter(n -> sameIds.contains(n.getTableId()) && n.getUpdateTime()
                        .isAfter(max)).map(DapDataModelTableDto::getTableId)
                .collect(Collectors.toList()); // 发生变化的表id
        List<DapDataModelTableDto> nowList = newModel.stream().filter(n -> modifyIds.contains(n.getTableId()))
                .sorted(Comparator.comparing(DapDataModelTableDto::getTableId))
                .collect(Collectors.toList()); // 新数据变化的表
        List<DapDataModelTableDto> oldList = oldModel.stream().filter(o -> modifyIds.contains(o.getPId()))
                .sorted(Comparator.comparing(DapDataModelTableDto::getPId))
                .collect(Collectors.toList()); // 旧数据变化的表
        if (flag) { // true表示通过发布使用
            List<DapDataModelOperateHistory> list = Arrays.asList();
            return ResultBean.ok(list)
                    .addMoreData("addTable", addTable)
                    .addMoreData("oldList", oldList)
                    .addMoreData("deleteTable", deleteTable)
                    .addMoreData("nowList", nowList);
        }
        List<DapDataModelOperateHistory> result = tableContrast(nowList, oldList, databaseType); // 表对比
        if ((result.isEmpty() || nowList.isEmpty()) && addTable.isEmpty() && deleteTable.isEmpty()) {
            return ResultBean.error("当前模型不存在任何表结构变更，不允许发布");
        } else {
            List<DapDataModelOperateHistory> histories = tableHistory(addTable, CREATE_TABLE, databaseType, result); // 新增记录
            List<DapDataModelOperateHistory> list = tableHistory(deleteTable, DELETE_TABLE, databaseType, histories); // 删除记录
            return ResultBean.ok(list);
        }
    }

    /**
     * 表对比
     *
     * @return
     */
    public static List<DapDataModelOperateHistory> tableContrast(List<DapDataModelTableDto> nowList,
                                                                 List<DapDataModelTableDto> oldList,
                                                                 DatabaseType databaseType) {
        List<DapDataModelOperateHistory> histories = new ArrayList<>();
        Boolean flag = databaseType.equals(DatabaseType.PGSQL);
        script = flag ? new PostgreTableScript() : new HiveTableScript();
        AbsFieldScript fieldScript = flag ? script.postgreFieldScript : script.hiveFieldScript;
        AbsKeyScript keyScript = flag ? script.postgreKeyScript : script.mysqlKeyScript;
        for (int i = 0; i < nowList.size(); i++) {
            String schema = nowList.get(i).getTableSchema();
            Map<String, String> map = new HashMap<>();
            script.modifyTableScript(nowList.get(i), oldList.get(i), schema, map);
            List<DapDataModelTableField> newFields = nowList.get(i).getFieldList(); // 最新字段
            List<DapDataModelTableField> oldFields = oldList.get(i).getFieldList(); // 旧版本字段
            List<String> list = newFields.stream().map(DapDataModelTableField::getId).collect(Collectors.toList());
            List<String> sameIds = oldFields.stream().filter(o -> list.contains(o.getPId())). // 过滤出相同的id
                    map(DapDataModelTableField::getPId).collect(Collectors.toList());
            List<DapDataModelTableField> insertField = newFields.stream(). // 新增字段
                    filter(n -> !sameIds.contains(n.getId())).collect(Collectors.toList());
            List<DapDataModelTableField> deleteField = oldFields.stream(). // 删除字段
                    filter(o -> !sameIds.contains(o.getPId())).collect(Collectors.toList());
            List<DapDataModelTableField> sameOldFields = fieldRank(oldFields, sameIds, false); // 字段旧版本数据
            List<DapDataModelTableField> sameNewFields = fieldRank(newFields, sameIds, true); // 字段新版本数据
            if (!insertField.isEmpty()) { // 新增字段ddl语句
                fieldScript.addFieldScript(insertField, schema, nowList.get(i).getEngName(), map);
            }
            if (!deleteField.isEmpty()) { // 删除字段ddl语句
                fieldScript.deleteFieldScript(deleteField, schema, nowList.get(i).getEngName(), map);
            }
            if (!nowList.get(i).getKeyList().isEmpty() || !oldList.get(i).getKeyList().isEmpty()) { // pg和mysql数据库索引
                List<DapDataModelSubordinateKey> keyList = oldList.get(i).getKeyList();
                // 新旧数据的交集
                List<String> ids = nowList.get(i).getKeyList()
                        .stream().filter(n -> keyList.stream()
                                .map(DapDataModelSubordinateKey::getPId)
                                .anyMatch(id -> Objects.equals(n.getId(), id)))
                        .map(DapDataModelSubordinateKey::getId)
                        .collect(Collectors.toList());
                // 新增的索引
                List<DapDataModelSubordinateKey> addKey = nowList.get(i).getKeyList()
                        .stream()
                        .filter(n -> !ids.contains(n.getId()))
                        .collect(Collectors.toList());
                // 删除的索引
                List<DapDataModelSubordinateKey> delKey = keyList
                        .stream()
                        .filter(o -> !ids.contains(o.getPId()))
                        .collect(Collectors.toList());
                if (!addKey.isEmpty()) {
                    keyScript.addKeyScript(addKey, newFields, schema, nowList.get(i).getEngName(), map); // 新增索引ddl
                }
                if (!delKey.isEmpty()) {
                    keyScript.deleteKeyScript(delKey, nowList.get(i).getEngName(), map); // 删除索引ddl
                }
            }
            StringBuffer stringBuffer = new StringBuffer();
            for (int j = 0; j < sameNewFields.size(); j++) { // 字段对比
                String fieldScripts = fieldScript.modifyFieldScript(sameNewFields.get(j), sameOldFields.get(j), nowList.get(i).getEngName(), schema);
                stringBuffer.append(StringUtils.isNotBlank(fieldScripts) ? fieldScripts : "");
            }
            if (StringUtils.isNotBlank(stringBuffer.toString())) {
                map.put(Constant.MF, stringBuffer.toString());
            }
            if (!map.isEmpty()) {
                DapDataModelOperateHistory history = historyList(nowList.get(i), MODIFY_TABLE, databaseType);
                JSONObject jsonObject = (JSONObject) JSONObject.toJSON(map);
                history.setPublicContent(jsonObject.toString());
                histories.add(history);
            }
        }
        return histories;
    }

    /**
     * 新增或删除表的历史版本记录
     *
     * @param dto
     * @param changeType
     * @return
     */
    public static List<DapDataModelOperateHistory> tableHistory(List<DapDataModelTableDto> dto, Integer changeType,
                                                                DatabaseType databaseType, List<DapDataModelOperateHistory> list) {
        // 表集合不为空
        if (!dto.isEmpty()) {
            for (DapDataModelTableDto table : dto) {
                DapDataModelOperateHistory histories = historyList(table, changeType, databaseType);
                list.add(histories);
            }
        }
        return list;
    }

    /**
     * 生成版本历史实体
     *
     * @param table
     * @param changeType
     * @return
     */
    public static DapDataModelOperateHistory historyList(DapDataModelTableDto table, Integer changeType, DatabaseType databaseType) {

        script = databaseType.equals(DatabaseType.MYSQL) ? new MysqlTableScript() : databaseType.equals(DatabaseType.PGSQL)
                ? new PostgreTableScript() : new HiveTableScript();
        DapDataModelOperateHistory history = new DapDataModelOperateHistory();
        history.setModelId(table.getDataModelId());
        // 如果是删除类型拿的是pid
        history.setModelTableId(changeType == DELETE_TABLE ? table.getPId() : table.getTableId());
        history.setTableName(table.getName());
        history.setTableEngName(table.getEngName());
        history.setLastChangeType(changeType);
        Map<String, String> map = new HashMap<>();
        if (changeType == CREATE_TABLE) {
            map.put(Constant.CT, createSql(table));
            JSONObject jsonObject = (JSONObject) JSONObject.toJSON(map);
            history.setPublicContent(jsonObject.toString());
        } else if (changeType == DELETE_TABLE) {
            script.deleteTableScript(table.getEngName(), table.getTableSchema(), map);
            JSONObject jsonObject = (JSONObject) JSONObject.toJSON(map);
            history.setPublicContent(jsonObject.toString());
        }
        return history;
    }

    /**
     * 生成sql
     *
     * @param table
     * @return
     */
    public static String createSql(DapDataModelTableDto table) {

        ModelTableInfoDto tableInfo = new ModelTableInfoDto();
        BeanUtils.copyProperties(table, tableInfo);
        List<SubordinateKeyDto> list = new ArrayList(); // 索引
        if (!table.getKeyList().isEmpty()) {
            table.getKeyList().forEach(k -> { // 封装索引信息
                SubordinateKeyDto subordinateKeyDto = new SubordinateKeyDto();
                List<DapDataModelTableField> collect = table.getFieldList()
                        .stream()
                        .filter(f -> k.getFieldIds().contains(f.getId()))
                        .collect(Collectors.toList());
                BeanUtils.copyProperties(k, subordinateKeyDto);
                subordinateKeyDto.setFieldNames(collect);
                list.add(subordinateKeyDto);
            });
        }
        return script.createTableScript(tableInfo, list, table.getPartitionList());
    }

    /**
     * 生成发布记录对象
     *
     * @param modelId
     * @return
     */
    public static DapDataModelRecord entity(String modelId) {

        DapDataModelRecord dapDataModelRecord = new DapDataModelRecord();
        dapDataModelRecord.setModelId(modelId);
        dapDataModelRecord.setApplicationTime(LocalDateTime.now());
        dapDataModelRecord.setApplicationBy(UserInfoHolder.getAccount());
        dapDataModelRecord.setPublicStatus(2);
        dapDataModelRecord.setChangeOrder("");
        dapDataModelRecord.setChangeOrder(String.valueOf(new Date().getTime() / 1000));
        return dapDataModelRecord;
    }

    /**
     * 表版本对比
     *
     * @param newVersion
     * @param oldVersion
     * @return
     */
    public static List<ContrastTableInfo> tableContrast(DapDataModelVersion newVersion, DapDataModelVersion oldVersion,
                                                        DapDataModelRecord newRecord, DapDataModelRecord oldRecord) {

        List<ContrastTableInfo> tableList = Lists.newArrayList();
        JSONObject newObject = JSON.parseObject(newVersion.getVersionContent());
        DapDataModelTableDto newTableDto = JSONObject.toJavaObject(newObject, DapDataModelTableDto.class);
        JSONObject oldObject = JSON.parseObject(oldVersion.getVersionContent());
        DapDataModelTableDto oldTableDto = JSONObject.toJavaObject(oldObject, DapDataModelTableDto.class);
        Map<String, List<ContrastFieldInfoDto>> map = tableFieldContrast(newTableDto.getFieldList(), oldTableDto.getFieldList());
        ContrastTableInfo newTableInfo = new ContrastTableInfo();
        ContrastTableInfo oldTableInfo = new ContrastTableInfo();
        if (!map.isEmpty()) {
            // 较新版本的数据
            newTableInfo.setId(newTableDto.getPId());
            newTableInfo.setChangeOrder(newRecord.getChangeOrder());
            newTableInfo.setReleaseTime(newRecord.getReleaseTime());
            newTableInfo.setApplicationBy(newRecord.getApplicationBy());
            newTableInfo.setFieldList(map.get("newFieldList"));
            tableList.add(newTableInfo);
            // 旧版本数据
            oldTableInfo.setId(oldTableDto.getPId());
            oldTableInfo.setChangeOrder(oldRecord.getChangeOrder());
            oldTableInfo.setReleaseTime(oldRecord.getReleaseTime());
            oldTableInfo.setApplicationBy(oldRecord.getApplicationBy());
            oldTableInfo.setFieldList(map.get("oldFieldList"));
            tableList.add(oldTableInfo);
        }
        // 获得字段
        return tableList;

    }

    /**
     * 字段对比
     *
     * @param one
     * @param two
     */
    public static Map<String, List<ContrastFieldInfoDto>> tableFieldContrast(List<DapDataModelTableField> one, List<DapDataModelTableField> two) {

        // 字段id集合
        List<String> ids = one.stream().map(DapDataModelTableField::getPId).collect(Collectors.toList());
        // 相同id
        List<String> sameIds = two.stream().filter(t -> ids.contains(t.getPId())).map(DapDataModelTableField::getPId).collect(Collectors.toList());
        // 版本一
        List<DapDataModelTableField> fieldListOne = one.stream().filter(o -> sameIds.contains(o.getPId())).sorted(Comparator.comparing(DapDataModelTableField::getPId)).collect(Collectors.toList());
        // 版本二
        List<DapDataModelTableField> fieldListTwo = two.stream().filter(t -> sameIds.contains(t.getPId())).sorted(Comparator.comparing(DapDataModelTableField::getPId)).collect(Collectors.toList());
        // 新增的字段
        List<DapDataModelTableField> addFields = one.stream().filter(o -> !sameIds.contains(o.getPId())).collect(Collectors.toList());
        // 对比的最新版本数据
        List<ContrastFieldInfoDto> newFieldList = Lists.newArrayList();
        // 旧版本数据
        List<ContrastFieldInfoDto> oldFieldList = Lists.newArrayList();
        // 封装新数据
        if (!addFields.isEmpty()) {
            addFields.forEach(f -> {
                ContrastFieldInfoDto fieldDto = new ContrastFieldInfoDto();
                BeanUtils.copyProperties(f, fieldDto);
                newFieldList.add(transToBean(fieldDto, 1));
            });
        }
        // 删除的字段
        List<DapDataModelTableField> deleteFields = two.stream().filter(t -> !sameIds.contains(t.getPId())).collect(Collectors.toList());
        // 封装旧数据
        if (!deleteFields.isEmpty()) {
            deleteFields.forEach(d -> {
                ContrastFieldInfoDto oldFieldDto = new ContrastFieldInfoDto();
                BeanUtils.copyProperties(d, oldFieldDto);
                oldFieldList.add(transToBean(oldFieldDto, 2));
            });
        }
        // 字段对比
        Boolean flag = false;
        List<ContrastFieldInfoDto> nowList = Lists.newArrayList();
        List<ContrastFieldInfoDto> oldList = Lists.newArrayList();
        for (int i = 0; i < fieldListOne.size(); i++) {
            ContrastFieldInfoDto newFieldDto = new ContrastFieldInfoDto();
            ContrastFieldInfoDto oldFieldDto = new ContrastFieldInfoDto();
            BeanUtils.copyProperties(fieldListOne.get(i), newFieldDto);
            BeanUtils.copyProperties(fieldListTwo.get(i), oldFieldDto);
            if (!Objects.equals(fieldListOne.get(i).getFieldName(), fieldListTwo.get(i).getFieldName())) {
                newFieldDto.setFieldNameIsChange(MODIFY_TABLE);
                oldFieldDto.setFieldNameIsChange(MODIFY_TABLE);
                flag = true;
            }
            // 字段注释
            if (!Objects.equals(fieldListOne.get(i).getComment(), fieldListTwo.get(i).getComment())) {
                newFieldDto.setCommentIsChange(MODIFY_TABLE);
                oldFieldDto.setCommentIsChange(MODIFY_TABLE);
                flag = true;
            }
            // 数据类型
            if (!Objects.equals(fieldListOne.get(i).getDataType(), fieldListTwo.get(i).getDataType())) {
                newFieldDto.setDataTypeIsChange(MODIFY_TABLE);
                oldFieldDto.setDataTypeIsChange(MODIFY_TABLE);
                flag = true;
            }
            // 长度
            if (!Objects.equals(fieldListOne.get(i).getLength(), fieldListTwo.get(i).getLength())) {
                newFieldDto.setLengthIsChange(MODIFY_TABLE);
                oldFieldDto.setLengthIsChange(MODIFY_TABLE);
                flag = true;
            }
            // 小数位
            if (fieldListOne.get(i).getDecimalLength() != fieldListTwo.get(i).getDecimalLength()) {
                newFieldDto.setDecimalLengthIsChange(MODIFY_TABLE);
                oldFieldDto.setDecimalLengthIsChange(MODIFY_TABLE);
                flag = true;
            }
            // 主键
            if (!Objects.equals(fieldListOne.get(i).getPrimaryKey(), fieldListTwo.get(i).getPrimaryKey())) {
                newFieldDto.setPrimaryKeyIsChange(MODIFY_TABLE);
                oldFieldDto.setPrimaryKeyIsChange(MODIFY_TABLE);
                flag = true;
            }
            // 非空
            if (!Objects.equals(fieldListOne.get(i).getNotNull(), fieldListTwo.get(i).getNotNull())) {
                newFieldDto.setNotNullIsChange(MODIFY_TABLE);
                oldFieldDto.setNotNullIsChange(MODIFY_TABLE);
                flag = true;
            }
            // 缺省
            if (!Objects.equals(fieldListOne.get(i).getDefaultValue(), fieldListTwo.get(i).getDefaultValue())) {
                newFieldDto.setDefaultValueIsChange(MODIFY_TABLE);
                oldFieldDto.setDefaultValueIsChange(MODIFY_TABLE);
                flag = true;
            }
            // 自增
            if (!Objects.equals(fieldListOne.get(i).getAutoIncrement(), fieldListTwo.get(i).getAutoIncrement())) {
                newFieldDto.setAutoIncrDefaultValueIsChange(MODIFY_TABLE);
                oldFieldDto.setAutoIncrDefaultValueIsChange(MODIFY_TABLE);
                flag = true;
            }
            // 初始值
            if (!Objects.equals(fieldListOne.get(i).getAutoIncrDefaultValue(), fieldListTwo.get(i).getAutoIncrDefaultValue())) {
                newFieldDto.setAutoIncrDefaultValueIsChange(MODIFY_TABLE);
                oldFieldDto.setAutoIncrDefaultValueIsChange(MODIFY_TABLE);
                flag = true;
            }
            // 无符号
            if (!Objects.equals(fieldListOne.get(i).getUnSigned(), fieldListTwo.get(i).getUnSigned())) {
                newFieldDto.setUnSignedIsChange(MODIFY_TABLE);
                oldFieldDto.setUnSignedIsChange(MODIFY_TABLE);
                flag = true;
            }
            // 填充零
            if (!Objects.equals(fieldListOne.get(i).getZeroFill(), fieldListTwo.get(i).getZeroFill())) {
                newFieldDto.setZeroFillIsChange(MODIFY_TABLE);
                oldFieldDto.setZeroFillIsChange(MODIFY_TABLE);
                flag = true;
            }
            // 业务描述
            if (!Objects.equals(fieldListOne.get(i).getBusinessDesc(), fieldListTwo.get(i).getBusinessDesc())) {
                newFieldDto.setBusinessDescIsChange(MODIFY_TABLE);
                oldFieldDto.setBusinessDescIsChange(MODIFY_TABLE);
                flag = true;
            }
            nowList.add(newFieldDto);
            oldList.add(oldFieldDto);
        }
        // 封装数据
        Map<String, List<ContrastFieldInfoDto>> map = new HashMap<>();
        // 都为空
        if (newFieldList.isEmpty() && oldFieldList.isEmpty() && !flag) {
            return map;
        }
        newFieldList.addAll(nowList);
        oldFieldList.addAll(oldList);
        map.put("newFieldList", newFieldList);
        map.put("oldFieldList", oldFieldList);
        return map;
    }

    /**
     * 对象转换
     *
     * @param fieldDto
     */
    public static ContrastFieldInfoDto transToBean(ContrastFieldInfoDto fieldDto, Integer status) {

        fieldDto.setAutoIncrDefaultValueIsChange(status);
        fieldDto.setFieldNameIsChange(status);
        fieldDto.setCommentIsChange(status);
        fieldDto.setDataTypeIsChange(status);
        fieldDto.setLengthIsChange(status);
        fieldDto.setDecimalLengthIsChange(status);
        fieldDto.setPrimaryKeyIsChange(status);
        fieldDto.setNotNullIsChange(status);
        fieldDto.setDefaultValueIsChange(status);
        fieldDto.setAutoIncrementIsChange(status);
        fieldDto.setUnSignedIsChange(status);
        fieldDto.setZeroFillIsChange(status);
        fieldDto.setBusinessDescIsChange(status);
        return fieldDto;

    }

    /**
     * 表对比结构的脚本封装成对象数据入库
     *
     * @param list
     */
    public static List<DapDataModelOperateHistory> sqlScriptToData(List<ModelCompareVo> list, String recordId,
                                                                   List<DapDataModelTable> tableList) {

        // 新建表脚本
        List<DapDataModelOperateHistory> historyList = Lists.newArrayList();
        list.forEach(m -> {
            Map<String, String> map = new HashMap<>();
            DapDataModelOperateHistory history = new DapDataModelOperateHistory();
            tableList.forEach(t -> {
                if (t.getId().equals(m.getTableId())) {
                    history.setModelTableId(t.getPId().equals("0") ? t.getId() : t.getPId());
                    history.setTableName(t.getName());
                }
            });
            // 默认为修改表
            history.setLastChangeType(MODIFY_TABLE);
            history.setModelId(m.getModelId());
            history.setTableEngName(m.getTableName());
            // history.setPublicTime(autoVerifyFlag ? LocalDateTime.now() : null);
            // 表级对比
            if (null != m.getTableCompares()) {
                m.getTableCompares().forEach(t -> {
                    Integer status = t.getModifyType().equals(ModifyType.CREATE) ? CREATE_TABLE :
                            t.getModifyType().equals(ModifyType.ALTER) ? MODIFY_TABLE : DELETE_TABLE;
                    history.setLastChangeType(status);
                    map.put(t.getModifyType().getDesc() + t.getModifyLevel().getDesc(), t.getData().getScript().getSql());
                });
            }
            // 字段级对比
            if (null != m.getFieldCompares()) {
                // 新增语句集合
                String createFields = m.getFieldCompares().stream().filter(f -> f.getModifyType().equals(ModifyType.CREATE))
                        .map(CompareResult::getData).map(SqlCompareResult::getScript).map(BmScript::getSql).collect(Collectors.joining(";"));
                // 修改语句集合
                String modifyFields = m.getFieldCompares().stream().filter(f -> f.getModifyType().equals(ModifyType.ALTER))
                        .map(CompareResult::getData).map(SqlCompareResult::getScript).map(BmScript::getSql).collect(Collectors.joining(";"));
                // 删除语句集合
                String dropFields = m.getFieldCompares().stream().filter(f -> f.getModifyType().equals(ModifyType.DROP))
                        .map(CompareResult::getData).map(SqlCompareResult::getScript).map(BmScript::getSql).collect(Collectors.joining(";"));
                // 存入集合
                if (StringUtils.isNotBlank(createFields)) {
                    map.put(ModifyType.CREATE.getDesc() + ModifyType.ModifyLevel.FIELD.getDesc(), createFields);
                }
                if (StringUtils.isNotBlank(modifyFields)) {
                    map.put(ModifyType.ALTER.getDesc() + ModifyType.ModifyLevel.FIELD.getDesc(), modifyFields);
                }
                if (StringUtils.isNotBlank(dropFields)) {
                    // 字段级sql脚本
                    map.put(ModifyType.DROP.getDesc() + ModifyType.ModifyLevel.FIELD.getDesc(), dropFields);
                }
            }
            // 索引对比
            if (null != m.getIndexCompares()) {
                // 新增索引
                String createIndex = m.getIndexCompares().stream().filter(f -> f.getModifyType().equals(ModifyType.CREATE))
                        .map(CompareResult::getData).map(SqlCompareResult::getScript).map(BmScript::getSql).collect(Collectors.joining(";"));
                // 修改索引
                String modifyIndex = m.getIndexCompares().stream().filter(f -> f.getModifyType().equals(ModifyType.ALTER))
                        .map(CompareResult::getData).map(SqlCompareResult::getScript).map(BmScript::getSql).collect(Collectors.joining(";"));
                // 删除索引
                String dropIndex = m.getIndexCompares().stream().filter(f -> f.getModifyType().equals(ModifyType.DROP))
                        .map(CompareResult::getData).map(SqlCompareResult::getScript).map(BmScript::getSql).collect(Collectors.joining(";"));
                // 存入集合
                if (StringUtils.isNotBlank(createIndex)) {
                    map.put(ModifyType.CREATE.getDesc() + ModifyType.ModifyLevel.INDEX.getDesc(), createIndex);
                }
                if (StringUtils.isNotBlank(modifyIndex)) {
                    map.put(ModifyType.ALTER.getDesc() + ModifyType.ModifyLevel.INDEX.getDesc(), modifyIndex);
                }
                if (StringUtils.isNotBlank(dropIndex)) {
                    map.put(ModifyType.DROP.getDesc() + ModifyType.ModifyLevel.INDEX.getDesc(), dropIndex);
                }
            }
            if (!map.isEmpty()) {
                JSONObject jsonObject = (JSONObject) JSONObject.toJSON(map);
                history.setPublicContent(jsonObject.toString());
                history.setDataModelRecordId(recordId);
                historyList.add(history);
            }
        });
        return historyList;
    }

    /**
     * 字段重新排序
     *
     * @param list
     * @return
     */
    public static List<DapDataModelTableField> fieldRank(List<DapDataModelTableField> list, List<String> sameIds, boolean flag) {
        // 拿到最大的序号
        Integer max = list.stream().map(DapDataModelTableField::getFieldRank)
                .max((e1, e2) -> e1.compareTo(e2)).get();
        List<DapDataModelTableField> sameNewFields = list.stream()
                .filter(n -> sameIds.contains(flag ? n.getId() : n.getPId()))
                .sorted(Comparator.comparing(DapDataModelTableField::getFieldRank))
                .peek(n -> n.setFieldRank(list.size() - (max - n.getFieldRank())))
                .collect(Collectors.toList()).stream()
                .sorted(Comparator.comparing(flag ? DapDataModelTableField::getId : DapDataModelTableField::getPId))
                .collect(Collectors.toList());
        return sameNewFields;
    }
}
